/**
 * @author        Nicolas Bottarini <nicolasbottarini@gmail.com>, 404 <http://www.proyecto404.com>
 * @version       $Rev: 3 $
 * @lastrevision  $Date: 2011-09-12 16:45:37 +0000 (Mon, 12 Sep 2011) $	 
 */
package com.proyecto404.core.collections {
	import com.proyecto404.core.BaseObject;
	import com.proyecto404.core.Check;
	import com.proyecto404.core.exception.NotImplementedException;
	
	public class Dictionary extends BaseObject implements IDictionary {
		private var _data:Object;
		private var _count:int;
		
		public function Dictionary(data:Object = null) {
			_data = new Object();
			_count = 0;
			if (data != null) {
				for (var key:* in data) {
					add(key, data[key]);
				}
			}
		}
		
		public function count():int {
			return _count;
		}
		
		public function isEmpty():Boolean {
			return count() == 0;
		}
		
		public function containsKey(key:String):Boolean {
			return key in _data;
		}
		
		public function containsValue(value:*):Boolean {
			for each(var item:* in _data) {
				if (areEquals(item, value)) {
					return true;
				}	
			}
			
			return false;
		}
		
		public function clear():void {
			_data = new Object();
			_count = 0;
		}
		
		public function add(key:String, value:*):void {
			if (!containsKey(key)) {
				_count++;
			}
			_data[key] = value;
		}
		
		public function addFromDictionary(dictionary:Dictionary):void {
			var it:IIterator = dictionary.getIterator();
			while(it.hasNext()) {
				var item:KeyValuePair = it.next() as KeyValuePair;
				add(item.key, item.value);
			}
		}
		
		public function removeKey(key:String):void {
			Check.require(containsKey(key), "Key not found");
			_count--;
			delete _data[key];
		}
		
		public function asReadOnly():ICollection {
			throw new NotImplementedException();
		}
		
		public function get(key:String):* {
			Check.require(containsKey(key), "Key not found");
			
			return _data[key];
		}
		
		public function getKeys():ICollection {
			var keys:List = new List();
			for(var key:String in _data) {
				keys.add(key);
			}
			return keys;
		}
		
		public function getValues():ICollection {
			var keys:List = new List();
			for(var key:String in _data) {
				keys.add(_data[key]);
			}
			return keys;
		}
		
		public function getIterator():IIterator {
			var items:List = new List();
			for(var key:String in _data) {
				items.add(new KeyValuePair(key, _data[key]));
			}
			return new ArrayIterator(items.toArray());
		}
	}
}